/* ----------------------------- Noble Steed Engine----------------------------*
Authors : Daniel Randle, Alex Bourne
Date Created : Mar 13 2013

File:
	nsmaparea.h

Description:
	This file contains the NSMapArea class which encapsulates drawing maps from a set of tile
	positions along with a mesh ID to say which tile the map will use to draw the tile
*---------------------------------------------------------------------------*/

#ifndef NSMAPAREA_H
#define NSMAPAREA_H

/* ---------------------------------Class NSTileMap-----------------------------*

Description:
	NSMapArea will populate the window by keeping track of all the tiles needed to draw a map.

*-------------------------------------------------------------------------------*/

// includes
#include <global.h>
#include <vector>
#include <nsmath3d.h>
#include <nsobjectreferenceset.h>
#include <nsobject.h>
#include <nstilegrid.h>

class NSObject;
class NSHexTile;
class NSSpotLight;
class NSPointLight;
class NSObjectReference;
class NSSpotLightReference;
class NSPointLightReference;
class NSShaderSet;
class NSDirectionLight;
class NSSelectionModel;
class NSCamera;
class NSShader;
class NSEngine;

class NSMapArea
{
public:

	typedef std::vector<NSObjectReferenceSet*>::iterator Iterator;
	typedef NSObjectReferenceSet::Iterator ObjectIterator;
	typedef NSObjectReferenceSet::RefIterator RefIterator;

	enum MapSize { 
		Small = 32, 
		Medium = 64, 
		Large = 96, 
		Huge = 128 };

	NSMapArea(NSEngine * eng, MapSize size = Medium);
	~NSMapArea();

	void addReference(NSObjectReference* toAdd);
	NSObjectReference * addReference(
		NSObject * baseObj, 
		const NSVec3Df & position, 
		const NSVec3Df & orientation = NSVec3Df(), 
		const NSVec3Df & scale = NSVec3Df(1.0f,1.0f,1.0f), 
		NSShaderSet * shaders = NULL);

	NSObjectReference * addReference(
		const std::string & objNm, 
		const NSVec3Df & position, 
		const NSVec3Df & orientation = NSVec3Df(), 
		const NSVec3Df & scale = NSVec3Df(1.0f,1.0f,1.0f), 
		NSShaderSet * shaders = NULL);

	void clear();
	NSObjectReference * createReference(
		NSObject * baseObj, 
		const NSVec3Df & position, 
		const NSVec3Df & orientation = NSVec3Df(), 
		const NSVec3Df & scale = NSVec3Df(1.0f,1.0f,1.0f), 
		NSShaderSet * shaders = NULL);

	void deserialize(std::ifstream & in);
	void drawOverlays(const NSMatrix4Df & projCamMat);

	NSDirectionLight * getDirectionalLight();
	NSEngine * getEngine();
	MapSize getMapSize();
	NSObjectReference * getReference(unsigned int refID, NSObject * baseObj);
	unsigned int getReferenceCount(NSObject * baseObj);
	NSSelectionModel * getSelectionModel();
	unsigned int getTotalReferenceCount();

	bool removeAllReferencesOf(NSObject * baseObj);
	bool removeReference(NSObjectReference * reference);
	bool removeReference(unsigned int refID, NSObject * baseObj);

	void resizeScreen(int _width, int _height);

	void serialize(std::ofstream & out);
	void setDirectionalLight(NSDirectionLight * dLight);
	void setProjectionMatrix(const NSMatrix4Df & proj);

	void update(NSObject * baseObj);
	void updateAll();

	int getScreenWidth();
	int getScreenHeight();

	Iterator begin();
	Iterator end();
	ObjectIterator objectsBegin(NSObject::ObjectType which);
	ObjectIterator objectsEnd(NSObject::ObjectType which);
	RefIterator refsBegin(NSObject * baseObj);
	RefIterator refsEnd(NSObject * baseObj);

private:

	std::vector<NSObjectReferenceSet *> referenceSets;
	NSSelectionModel * selModel;
	NSDirectionLight * directionalLight;
	NSTileGrid * tileGrid;
	NSEngine * engine;

	MapSize mapSize;
	int screenW;
	int screenH;
};

#endif